package in.muton.edushare.pages.curricula;

import in.muton.edushare.auth.roles.DeptRoleCheck;
import in.muton.edushare.auth.roles.UnivRoleCheck;
import in.muton.edushare.pages.EduShareBasePage;
import in.muton.edushare.pages.deptpages.DeptAcadProgs;
import in.muton.edushare.pages.univ.UnivAcadProgs;
import in.muton.edushare.processing.objects.UnivDataHandler;
import in.muton.edushare.url.EduShareURLPanel;
import in.muton.edushare.url.EntityPageParams;
import in.muton.edushare.url.URLLoader;
import in.muton.edushare.wicket.converters.choicerenderers.GenericRenderer;
import in.muton.edushare.wicket.models.CayenneList;
import in.muton.edushare.wicket.models.CayenneModel;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;

import com.edushare.common.constants.URLConstants;
import com.edushare.common.dao.CurriculumDAO;
import com.edushare.common.dao.DepartmentsDAO;
import com.edushare.common.dao.UniversitiesDAO;
import com.edushare.common.exceptions.EduShareRuntimeException;
import com.edushare.common.util.StringUtil;
import com.edushare.common.vo.Curricula;
import com.edushare.common.vo.Departments;
import com.edushare.common.vo.Universities;
import com.edushare.common.vo.Users;

public class NewCurriculaPage extends EduShareBasePage {

	private static final Log log = LogFactory.getLog(NewCurriculaPage.class);

	public NewCurriculaPage(PageParameters params) {
		initCurr(params);
		if (!isAuthorised(univModel, deptModel, getLoggedInUser())) {
			throw new RestartResponseException(URLLoader
					.getPageClass(URLConstants.UNAUTHORIZED_PATH));
		}

		Form<Void> f = new Form<Void>("newCurrPage");
		add(f);
		gr = new GenericRenderer<Integer>(getMap(), null);

		f.add(new Button("save") {
			@Override
			public void onSubmit() {
				if (!StringUtil.isValid(getCurrName())) {
					setErrorMessage("Academic program name is required");
					return;
				}

				log.debug("getCurrName = " + getCurrName());

				if (getCurrSems() == null) {
					setErrorMessage("An academic program must have at least one semester");
					return;
				}

				if (getCurrSems() < 1) {
					setErrorMessage("An academic program must have at least one semester");
					return;
				}
				if (gr.getSelection() == null) {
					setErrorMessage("A department for this academic program is required");
					return;
				}
				setErrorMessage("");
				Departments d = new DepartmentsDAO(getSessionORMInterface())
						.getDepartmentByPk(gr.getSelection());
				if (currModel == null) {
					CurriculumDAO cDAO = new CurriculumDAO(
							getSessionORMInterface());

					Curricula curr = cDAO.newCurriculum(getCurrName(), d,
							getCurrSems());
					curr.setCurriculaDesc(getCurrDesc());
					currModel = new CayenneModel<Curricula>(curr);
				} else {
					Curricula curr1 = currModel.getObject();
					curr1.setCurriculaDesc(getCurrDesc());
					curr1.setCurriculaName(getCurrName());
					curr1.setDepartment(d);
					curr1.setTotalSemester(getCurrSems());
					curr1.setUniversity(new DepartmentsDAO(
							getSessionORMInterface()).getParent(d));
				}
				getSessionORMInterface().commitAllChanges();
				PageParameters params = new PageParameters();
				params.put("0", currModel.getObject().getCurriculaId());
				CurriculaEditor coursePage = new CurriculaEditor(params);
				setResponsePage(coursePage);
			}

			private static final long serialVersionUID = -7533715080867833327L;
		});

		f.add(new Button("cancel") {
			@Override
			public void onSubmit() {
				if (deptModel == null)
					setResponsePage(UnivAcadProgs.class, EntityPageParams
							.getParams(univModel));
				else
					setResponsePage(DeptAcadProgs.class, EntityPageParams
							.getParams(deptModel));
			}

			private static final long serialVersionUID = -5583015605028852706L;
		});

		f.add(new TextArea<String>("currDesc", new PropertyModel<String>(this,
				"currDesc")));
		f.add(new TextField<String>("currName", new PropertyModel<String>(this,
				"currName")));
		f.add(new TextField<Integer>("currSems", new PropertyModel<Integer>(
				this, "currSems")));
		f.add(new DropDownChoice<String>("currDepartment", gr.getModel(), gr
				.getOptions(), gr));
		add(new Label("currDispName", getCurrName()));
		if (deptModel != null)
			add(new EduShareURLPanel("univLink", deptModel));
		else
			add(new EduShareURLPanel("univLink", univModel));
	}

	private void initCurr(PageParameters params) {
		String univId = params.getString("0");
		if (StringUtil.isValid(univId)) {
			Universities univ = new UniversitiesDAO(getSessionORMInterface())
					.getUnivById(univId);
			if (univ == null)
				throw new EduShareRuntimeException("Unable to find university");
			univModel = new CayenneModel<Universities>(univ);
		} else {
			throw new EduShareRuntimeException("Unable to find university");
		}

		String currId = params.getString("1");
		CurriculumDAO cDAO = new CurriculumDAO(getSessionORMInterface());
		if (StringUtil.isValid(currId) && !currId.equals("0")) {
			Curricula curr = cDAO.getCurriculaById(Integer.parseInt(currId));
			if (curr == null)
				throw new EduShareRuntimeException("Unable to find curr");
			currModel = new CayenneModel<Curricula>(curr);
		}

		String deptId = params.getString("2");
		DepartmentsDAO dDAO = new DepartmentsDAO(getSessionORMInterface());
		if (StringUtil.isValid(currId)) {
			Departments dept = dDAO.getDepartmentByPk(Integer.parseInt(deptId));
			if (dept == null)
				throw new EduShareRuntimeException("Unable to find department");
			deptModel = new CayenneModel<Departments>(dept);
		}

		if (currModel != null) {
			setCurrDesc(currModel.getObject().getCurriculaDesc());
			setCurrName(currModel.getObject().getCurriculaName());
			setCurrSems(currModel.getObject().getTotalSemester());
		}
	}

	private HashMap<String, Integer> getMap() {
		HashMap<String, Integer> map = new HashMap<String, Integer>();
		List<IModel<Departments>> deptList = getDepartments().getObject();
		for (IModel<Departments> dept : deptList) {
			map.put(dept.getObject().getDeptName(), dept.getObject()
					.getDepartmentId());
		}
		return map;
	}

	@Override
	public String getPageTitle() {
		return getLoggedInUser().getCompleteUserName() + " | "
				+ univModel.getObject().getUniversityName()
				+ " | New Academic Program | Edushare";
	}

	@Override
	public String getUserRole() {
		return "";
	}

	public void setCurrName(String currName) {
		this.currName = currName;
	}

	public String getCurrName() {
		return currName;
	}

	public void setCurrSems(Integer currSems) {
		this.currSems = currSems;
	}

	public Integer getCurrSems() {
		return currSems;
	}

	public void setCurrDesc(String currDesc) {
		this.currDesc = currDesc;
	}

	public String getCurrDesc() {
		return currDesc;
	}

	public static boolean isAuthorised(IModel<Universities> uModel,
			IModel<Departments> dModel, Users user) {
		UnivRoleCheck urc = new UnivRoleCheck(uModel.getObject(), user);
		if (urc.isAdmin())
			return true;
		if (dModel == null)
			return false;
		DeptRoleCheck drc = new DeptRoleCheck(dModel.getObject(), user);
		if (!drc.isAdmin())
			return false;
		return true;
	}

	private CayenneList<Departments> getDepartments() {
		CayenneList<Departments> deptList = new CayenneList<Departments>(null);
		if (univModel != null) {
			UnivRoleCheck urc = new UnivRoleCheck(univModel.getObject(),
					getLoggedInUser());
			if (urc.isAdmin()) {
				deptList.add(new UnivDataHandler(univModel).getAllDept());
				return deptList;
			}
		}
		if (deptModel != null) {
			deptList.add(deptModel);
		}
		return deptList;
	}

	private IModel<Departments> deptModel = null;
	private IModel<Universities> univModel = null;
	private IModel<Curricula> currModel = null;
	private String currName = "";
	private Integer currSems = new Integer(1);
	private String currDesc = "";
	private GenericRenderer<Integer> gr = null;
}
